package com.cinsea.salary;

import com.cinsea.common.IDGenerator;
import com.cinsea.common.JdbcDao;
import com.cinsea.security.util.JdbcUtil;
import com.cinsea.util.MathUtil;
import com.cinsea.util.NumberUtil;
import com.cinsea.util.SqlUtil;
import com.cinsea.util.StringUtil;
import oracle.sql.SQLUtil;
import org.apache.cxf.ws.addressing.MAPAggregator;
import org.directwebremoting.annotations.RemoteMethod;
import org.directwebremoting.annotations.RemoteProxy;
import org.omg.CORBA.OBJECT_NOT_EXIST;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.object.BatchSqlUpdate;
import org.springframework.stereotype.Service;
import uk.ltd.getahead.dwr.WebContext;
import uk.ltd.getahead.dwr.WebContextFactory;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Types;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

@RemoteProxy(name="SalaryService")
@Service
public class SalaryService {
    @Resource
    private JdbcDao jdbcDao;
    @RemoteMethod
    public int getCurrentCount() {
        int count = 0;
        WebContext ctx = WebContextFactory.get();
        Map countMap = (Map) ctx.getSession().getAttribute("salaryCount");
        if (countMap != null) {
            for (Object o : countMap.values()) {
                count += (Integer) o;
            }
        }
        return count;
    }
    @RemoteMethod
    public synchronized int salary(String month) {
        WebContext ctx = WebContextFactory.get();
        int total = 0;
        Map statusMap = (Map) ctx.getSession().getAttribute("salaryStatus");

        if (statusMap != null) {
            for (Object status : statusMap.values()) {
                if (((String) status).equals("0"))
                    return -1;
            }
        }

        HashMap countmap = new HashMap();
        HashMap statusmap = new HashMap();
        HashMap sizemap = new HashMap();
        ctx.getSession().setAttribute("salaryCount", countmap); //记数
        ctx.getSession().setAttribute("salaryStatus", statusmap); //任务状态
        String sql="delete from ut_salary where riqi=?";
        jdbcDao.update(sql,new Object[]{month});
        sql="select id,orgid,objno,objname,jbgz,sijin,gzqt,sijincom,guoji from cs_human where deleted=0 and hrstatus!=4 and orgid!='11111111111111111111111111111111'";
        List list = jdbcDao.getJdbcTemplate().queryForList(sql);
        total = list.size();
        ExecutorService exec = Executors.newFixedThreadPool(1);
        if (total == 0)
            return 0;

        statusmap.put("all", "0");
        countmap.put("all", new Integer(0));
        sizemap.put("all", list);
        SalaryTask task = new SalaryTask(this);
        task.setMonth(month);
        task.setResult(countmap);
        task.setStatus(statusmap);
        task.setSize(sizemap);
        exec.execute(task);
        exec.shutdown();
        return total;
    }
    public synchronized void doSalary(String month,Map countMap, Map statusMap,Map sizeMap ) {
        try {
            List users=(List) sizeMap.get("all");
            String userid;
            String gonghao;
            String xm;
            String bm;
            Float jbgz;
            Float sj;
            Float sjcom;
            Float kk;
            Float tc;
            Float yf;
            Float sf;
            Float tax;
            Float jdj;
            Float gzqt;
            Float gzflqt;
            String sql;
            String guoji;
            for (Object obj : users) {
                Map m=(Map)obj;
                jbgz= m.get("jbgz")==null?0:NumberUtil.string2Float(m.get("jbgz").toString(),0);
                sj=m.get("sijin")==null?0:NumberUtil.string2Float(m.get("sijin").toString(),0);
                sjcom=m.get("sijincom")==null?0:NumberUtil.string2Float(m.get("sijincom").toString(),0);
                gzqt=m.get("gzqt")==null?0:NumberUtil.string2Float(m.get("gzqt").toString(),0);
                userid= StringUtil.null2String(m.get("id"));
                gonghao= StringUtil.null2String(m.get("objno"));
                xm= StringUtil.null2String(m.get("objname"));
                bm= StringUtil.null2String(m.get("orgid"));
                List humanpermonth=jdbcDao.queryForList("select orgid from ut_humanpermonth where processid=? and riqi=?",new Object[]{userid,month});
                if(humanpermonth.size()>0){
                    Map currentmonthhuman=(Map)humanpermonth.get(0);
                    String currentmonthOrg=(String)currentmonthhuman.get("orgid");
                    if(!StringUtil.isEmpty(currentmonthOrg)) bm=currentmonthOrg;
                }
                guoji= StringUtil.null2String(m.get("guoji"));
                tc=ticheng(userid, month);
                if(tc==null) tc=0f;
                kk=  koukuan(userid, month);
                if(kk==null) kk=0f;
                jdj=jdj(userid,month);
                if(jdj==null) jdj=0f;
                gzflqt=gzflqt(userid,month);
                if(gzflqt==null) gzflqt=0f;
                yf=jbgz+tc+jdj+gzqt+gzflqt-kk-sj;
                String sdssl="bd1879522d03c895012d0cadecfe0189";
                if(!guoji.equals("40288a4a3712d7ce0137201737d70488")) sdssl="40288a4a3712d7ce013720118db50468";
                tax=tax(yf,sdssl);
                sf=yf-tax;
                sql="insert into ut_salary(xm,userid,bm,riqi,jbgz,sijin,koukuan,tc,jdj,gzqt,yf,sf,tax,gzflqt,sijincom)values(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
                jdbcDao.update(sql,new Object[]{xm,userid,bm,month,jbgz,sj,kk,tc,jdj,gzqt,yf,sf,tax,gzflqt,sjcom}) ;
                Object count = countMap.get("all");
                count = (Integer) count + 1;
                countMap.put("all", count);
            }
            statusMap.put("all", "1");
        } catch (Throwable e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            countMap.put("all", ((List) sizeMap.get("all")).size());
            statusMap.put("all", "1");
        }

    }
    public Float koukuan(String gonghao,String month){
        try {
            String sql="select sum(jine) as jine from ut_koukuan where riqi=? and renyuan=? and deleted=0 and finished=1";
            return (Float)jdbcDao.getJdbcTemplate().queryForObject(sql,new Object[]{month,gonghao},Float.class);
        } catch (Exception e) {
            e.printStackTrace();
            return 0.0f;
        }
    }
    public Float ticheng(String gonghao,String month){
        try {
            String sql="select sum(tc) as tc from ut_jjtc where riqi=? and renyuan=? and deleted=0";
            return (Float)jdbcDao.getJdbcTemplate().queryForObject(sql,new Object[]{month,gonghao},Float.class);
        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            return 0.0f;
        }
    }
    public Float jdj(String gonghao,String month){
        try {
            String sql="select sum(jdj) as jdj from ut_jjtc where riqi=? and renyuan=? and deleted=0";
            return (Float)jdbcDao.getJdbcTemplate().queryForObject(sql,new Object[]{month,gonghao},Float.class);
        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            return 0.0f;
        }
    }
    public Float gzflqt(String gonghao,String month){
        try {
            String sql="select sum(gzflqt) as jdj from ut_jjtc where riqi=? and renyuan=? and deleted=0";
            return (Float)jdbcDao.getJdbcTemplate().queryForObject(sql,new Object[]{month,gonghao},Float.class);
        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            return 0.0f;
        }
    }
    public Float tax(Float salary,String sdssl){
        try {
            Float qzd=NumberUtil.string2Float(jdbcDao.getJdbcTemplate().queryForObject("select qzd from ut_sdssl where processid=?",new Object[]{sdssl},Object.class).toString(),0);
            if(salary<qzd) return 0.0f;
            Map taxdata=jdbcDao.getJdbcTemplate().queryForMap("select rate,sskcs from ut_sdssldetail where ?>maxvalue and ?<=minvalue and processid=?",new Object[]{salary-qzd,salary-qzd,sdssl});
            Float tax=(salary-qzd)*NumberUtil.string2Float(taxdata.get("rate").toString(),0)/100- NumberUtil.string2Float(taxdata.get("sskcs").toString(),0);
            double tax_d=Double.parseDouble(tax+"");
            tax = (float)MathUtil.round(tax_d,2);
            return tax;
        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
            return 0.0f;
        }
    }
    public void saveHumanPerMonth(String month) {     //保存每月各工作地点人数
        String timepoint = month + "-15";
        String sql = "select processid,orgid,gzdd from cs_human where rzrq<=? and (" + SqlUtil.isNull("lzrq") + " or lzrq>?) ";
        List<Map> humans = jdbcDao.queryForList(sql, new Object[]{timepoint, timepoint});
        sql = "delete from ut_humanpermonth where riqi=?";
        jdbcDao.update(sql, new Object[]{month});
        sql = "insert into ut_humanpermonth(id,processid,orgid,gzdd,riqi) values(?,?,?,?,?)";
        BatchSqlUpdate bsu = new BatchSqlUpdate(jdbcDao.getDataSource(), sql);
        bsu.setBatchSize(20);
        bsu.setTypes(new int[]{Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR});
        for (Map humandata : humans) {
            String id = IDGenerator.getUnquieID();
            String processid = (String) humandata.get("processid");
            String orgid = (String) humandata.get("orgid");
            String gzdd = (String) humandata.get("gzdd");
            bsu.update(new Object[]{id, processid, orgid, gzdd, month});
        }
        bsu.flush();
    }
    public void saveHumanFyftPerMonth(String month) {     //按工作地点分摊当月成本
        String gtfySql = "select bm,sum(jine) as jine from view_gtfy where riqi=? group by bm";
        String gdzcSql = "select bm,sum(jine) as jine from view_gdzc where riqi<=? and lastdate>=? group by bm";
        String humanSql = "select processid,orgid,gzdd from ut_humanpermonth where riqi=? and " + SqlUtil.isNotNull("gzdd");
        String countSql = "select count(processid) as humancount,gzdd from ut_humanpermonth where riqi=? and " + SqlUtil.isNotNull("gzdd") + " group by gzdd";
        List<Map> gdzcList = jdbcDao.queryForList(gdzcSql, new Object[]{month,month});
        List<Map> gtfyList = jdbcDao.queryForList(gtfySql, new Object[]{month});
        List<Map> humanList = jdbcDao.queryForList(humanSql, new Object[]{month});
        List<Map> countList = jdbcDao.queryForList(countSql, new Object[]{month});
        int total = humanList.size();
        if (total == 0) return;
        String sql = "delete from ut_humanfyftpermonth where riqi=?";
        jdbcDao.update(sql, new Object[]{month});
        sql = "insert into ut_humanfyftpermonth(id,processid,orgid,gzdd,riqi,gdzc,gdzcg,gtfy,gtfyg) values(?,?,?,?,?,?,?,?,?)";
        BatchSqlUpdate bsu = new BatchSqlUpdate(jdbcDao.getDataSource(), sql);
        bsu.setBatchSize(20);
        bsu.setTypes(new int[]{Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.VARCHAR, Types.FLOAT, Types.FLOAT, Types.FLOAT, Types.FLOAT});
        for (Map human : humanList) {
            String id = IDGenerator.getUnquieID();
            String processid = (String) human.get("processid");
            String orgid = (String) human.get("orgid");
            String gzdd = (String) human.get("gzdd");
            Long persons =  (Long)getValueFromMapList(countList,"humancount","gzdd", gzdd);
            Float gdzcFt;
            BigDecimal tmp = (BigDecimal) getValueFromMapList(gdzcList,"jine","bm", gzdd);
            if (tmp != null && persons != null) gdzcFt = NumberUtil.string2Float(tmp.toString()) / persons;
            else gdzcFt = 0.0f;
            Float gdzcFtg;
            tmp = (BigDecimal) getValueFromMapList(gdzcList,"jine","bm", "11111111111111111111111111111111");
            if (tmp != null) gdzcFtg = NumberUtil.string2Float(tmp.toString()) / humanList.size();
            else gdzcFtg = 0.0f;
            Float gtfyFt;
            tmp = (BigDecimal) getValueFromMapList(gtfyList,"jine","bm", gzdd);
            if (tmp != null && persons != null) gtfyFt = NumberUtil.string2Float(tmp.toString()) / persons;
            else gtfyFt = 0.0f;
            Float gtfyFtg;
            tmp = (BigDecimal) getValueFromMapList(gtfyList,"jine","bm", "11111111111111111111111111111111");
            if (tmp != null) gtfyFtg = NumberUtil.string2Float(tmp.toString()) / humanList.size();
            else gtfyFtg = 0.0f;
            bsu.update(new Object[]{id, processid, orgid, gzdd, month, gdzcFt, gdzcFtg, gtfyFt, gtfyFtg});
        }
        bsu.flush();

    }

    private Object getValueFromMapList(List<Map> l,String returnkey, String key,String value) {
        Object o = null;
        String keyval;
        for (Map map : l) {
             keyval= (String)map.get(key);
            if (keyval.equals(value)) return map.get(returnkey);
        }
        return o;
    }
}
class SalaryTask implements Runnable {

    private SalaryService salaryService;


    public SalaryTask(SalaryService salaryService) {
        this.salaryService = salaryService;
    }

    public Map getResult() {
        return result;
    }

    public void setResult(Map result) {
        this.result = result;
    }

    public Map getSize() {
        return size;
    }

    public void setSize(Map size) {
        this.size = size;
    }

    public Map getStatus() {
        return status;
    }

    public void setStatus(Map status) {
        this.status = status;
    }

    public String getMonth() {
        return month;
    }

    public void setMonth(String month) {
        this.month = month;
    }

    private Map result;

    private Map status;

    private Map size;
    private String month;
    public void run() {
       salaryService.doSalary(month,result, status, size);
    }

    public static void main(String[] args) {
        float yf=3703.25f;
        Float tax=(yf-2000)*NumberUtil.string2Float("10",0)/100- NumberUtil.string2Float("25",0);
        double tax_d=Double.parseDouble(tax+"");
            tax = (float)MathUtil.round(tax_d,2);
        System.out.println(tax);
    }
}
